home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 06 - 1990 / 06.01 Jan 90 / Ghost Fonts.text next >
Encoding:
Text File  |  1989-11-02  |  10.3 KB  |  435 lines  |  [TEXT/nX^n]

  1.  
  2.  
  3.     /* styleListHdl is a handle to document's style list */
  4.     styleCount = (*styleListHdl)->count;
  5.         
  6.     /* allocate temp buffer to hold list of font IDs used */
  7.     if (!(fontBufHdl = NewHandle (sizeof (short) * styleCount))))
  8.     {
  9.         err = kNotEnufMem;    /* can't allocate */
  10.         goto doneErr;
  11.     }
  12.     
  13.     localFontCount = 0;
  14.     fontBuf = *fontBufHdl;    
  15.     /* dereference handle for efficiency */
  16.     /* 
  17.         NOTE that nothing in this next loop compacts the heap so this pointer will be valid without locking the handle 
  18.     */
  19.  
  20.     /* loop through style list, making one entry in fontBuf for each unique font ID in the list */
  21.     for (styleIndex = 0; styleIndex < styleCount; styleIndex++)
  22.     {
  23.         /* get next style list element font number */
  24.         fontID = (*styleListHdl)->style [styleIndex].font;
  25.  
  26. /* loop through fontBuf to see if we already have font */ 
  27.         font = 0;
  28.         while (font < localFontCount)
  29.         {
  30.             if (fontBuf [font] == fontID)     /*found it, not unique*/
  31.                 break;
  32.  
  33.             font++;
  34.         }
  35.         
  36.         if (font == localFontCount)    
  37.             /* this case if unique, add it */
  38.             fontBuf [localFontCount++] = fontID; 
  39.     }
  40.     
  41.     /* write the FontList.count (localFontCount) */
  42.     if (err = writeDataSize (localFontCount, fileRef))
  43.         goto doneErr;
  44.     
  45.     /* write FontList.fontMap (FontMap array) to disk */
  46.     for (fontIndex = 0; fontIndex < localFontCount; fontIndex++)        {    
  47.         fontID = fontBuf [fontIndex];
  48.         getLocalFontName (fontID, fontName);
  49.         
  50.         /* write font number */
  51.         nWrite = sizeof (fontID);
  52.         if (err = FSWrite (fileRef, &nWrite, &fontID))
  53.             goto doneErr;
  54.  
  55.         /* write font name */
  56.         nWrite = fontName [0] + 1;        
  57.         if (err = FSWrite (fileRef, &nWrite , fontName))
  58.             goto doneErr;
  59.     }
  60.  
  61.     DisposHandle (fontBufHdl);    /* free temporary buffer */
  62.  
  63.  
  64.  
  65.     readSize = nRead = (Size) sizeof (short);        /* read font count */
  66.     if (err = FSRead (fileRef, &nRead, &fontCount))
  67.         goto doneErr;
  68.     
  69.     if (nRead != readSize)
  70.     {
  71.         err = kBadFileFormat;
  72.         goto doneErr;
  73.     }
  74.                 
  75.     if (!(ghostFontTbl = NewHandle ((Size)(sizeof (FontList) + 
  76.         (sizeof (FontMap) * (fontCount-1))))))
  77.     {
  78.         err = kNotEnufMem;
  79.         goto doneErr;
  80.     }
  81.  
  82.     if (!(fontMapHdl = NewHandle ((sizeof (short) * (fontCount << 1)))))
  83.     {
  84.         DisposHandle (ghostFontTbl);
  85.         err = kNotEnufMem;
  86.         goto doneErr;
  87.     }
  88.     
  89.     MoveHHi (ghostFontTbl);
  90.     HLock (ghostFontTbl);
  91.  
  92.     fontMapIndex = 0;
  93.  
  94.     (*ghostFontTbl)->count = 0;
  95.     ghostFontPtr = (*ghostFontTbl)->fontMap;
  96.     
  97.     for (index = 0; index < fontCount; index++)
  98.     {
  99.         /* read font number */
  100.         readSize = nRead = (Size) sizeof (short);    
  101.         if (err = FSRead (fileRef, &nRead, &localFont))
  102.             goto doneErr;
  103.         if (nRead != readSize)
  104.         {
  105.             err = kBadFileFormat;
  106.             goto doneErr;
  107.         }
  108.  
  109.         /* read string length */
  110.         readSize = nRead = 1;
  111.         err = FSRead (fileRef, &nRead, localFontStr);
  112.         /* error check */
  113.     
  114.         /* read font name string */
  115.         readSize = nRead = localFontStr[0];
  116.         err = FSRead (fileRef, &nRead, &localFontStr[1]);
  117.         /* more error checking */
  118.  
  119.  
  120.         /* get the system's idea of a font number for this font */
  121.         GetFNum (localFontStr, &systemFont);
  122.  
  123.         if (systemFont)    /* the font exists */
  124.         {
  125.             if (systemFont != localFont)     /* agree with ours ? */
  126.             {
  127.                 /* case 3: font number conflicts */
  128.                 /* store localFont, system font in this map */
  129.                 *(*fontMapHdl + fontMapIndex++) = localFont;
  130.                 *(*fontMapHdl + fontMapIndex++) = systemFont;
  131.             }
  132.             else    
  133.             {
  134.                 /* case 1: we agree on the number */
  135.                 /* nothing to do here but I wanted you to see where
  136.                     this case was detected */
  137.             }
  138.         }
  139.         else    /* font is not resident in this system */
  140.         {
  141.             /* this code is taken from Apple tech note */
  142.  
  143.             /* get system font name */
  144.             GetFontName (0, systemFontStr);
  145.  
  146.             /* does it compare with our font name ? */
  147.             if (!EqualString (localFontStr, systemFontStr, false,false))
  148.             {
  149.                 /* case 2: this is a Ghost Font */
  150.                 pStrCpy (ghostFontPtr->fontName, localFontStr);
  151.                 ghostFontPtr->fontNumber = localFont;
  152.         
  153.                 (*ghostFontTbl)->count++;
  154.                 ghostFontPtr++;
  155.             }
  156.         }
  157.     } /* read font list loop */
  158.  
  159.     /* make the pass through the style list and change conflicting fonts */
  160.     count = (*styleListHdl)->count;    
  161.     for (styleIndex = 0; styleIndex < count; styleIndex++)
  162.     {
  163.         for (index = 0 ; index < (fontMapIndex >> 1) ; index += 2)
  164.         {
  165.             localFont = *(*fontMapHdl + index);
  166.             systemFont = *(*fontMapHdl + index + 1);
  167.             
  168.             if ((*styleListHdl)->style [styleIndex].font == localFont)
  169.             {
  170.                 /* change style list */
  171.                 (*styleListHdl)->style [styleIndex].font = systemFont;
  172.                 break;
  173.             }
  174.         }
  175.     }
  176.     
  177.     HUnlock (ghostFontTbl);
  178.     disposeHdl (fontMapHdl);    /* no longer need map */
  179.  
  180.     if ((*ghostFontTbl)->count)
  181.     {
  182.         count = sizeof (FontList) + (sizeof (FontMap) *                     ((*ghostFontTbl)->count - 1));
  183.         SetHandleSize (ghostFontTbl, (Size)count);
  184.         if (err = MemErr ())
  185.             goto doneErr;
  186.     }
  187.     else
  188.     {
  189.         DisposHandle (ghostFontTbl);
  190.         ghostFontTbl = 0L;
  191.     }
  192.  
  193.     theDoc->ghostFontList = ghostFontTbl;
  194.  
  195.  
  196.  
  197. #define kGhostFontChar        '*'    /* asterisk flags these fonts */
  198. #define kGhostFontDelim        '-'/* dashes delimit Ghost Fonts */
  199. /* ---------------------------------------------------------
  200.     buildFontMenu -    create the font menu from the document's ghost list
  201.     © 1989 by Macreations. All Rights Reserved
  202. ---------------------------------------------------------- */
  203. MenuHandle
  204. buildFontMenu (theDoc, fontMenuHdl)
  205.     DocPtr            theDoc;
  206.     MenuHandle            fontMenuHdl;
  207. {
  208.     register char        *fontNamePtr, *fontMapNamePtr;
  209.     FontListHdl            fontListHdl;
  210.     FontMapPtr            fontMapPtr;
  211.  
  212.     register short        count, font, fontCharCount;
  213.     Str255            fontStr, delimitStr;
  214.  
  215.     if (!fontMenuHdl)        /* first time, init menu */
  216.     {
  217.         delimitStr [0] = 1;            /* create delimiter string */
  218.         delimitStr [1] = kGhostFontDelim;
  219.  
  220.         AddResMenu (fontMenuHdl, 'FONT');    /* create menu */
  221.         AppendMenu (fontMenuHdl, delimitStr);
  222.         InsertMenu (fontMenuHdl, hierMenu);
  223.     }
  224.     else if (count = CountMItems (fontMenuHdl))    /* strip old Ghost Fonts     {                                    from menu */
  225.         /* search menu from the bottom up */
  226.         GetItem (fontMenuHdl, count, fontStr);
  227.  
  228.         /* search for dashed line delimiter,
  229.             delete all items until found */
  230.         while (fontStr[1] != kGhostFontDelim)
  231.         {
  232.             DelMenuItem (fontMenuHdl, count--);
  233.             GetItem (fontMenuHdl, count, fontStr);
  234.         }
  235.     }
  236.     
  237.     if (theDoc)
  238.     {
  239.         if (fontListHdl = theDoc->ghostFontList)
  240.         {
  241.             if (count = (*fontListHdl)->count)
  242.             {
  243.                 /* add the Ghost Fonts to the menu */
  244.                 for (font = 0; font < count; font++)
  245.                 {
  246.                     fontMapPtr = (*fontListHdl)->fontMap + font;
  247.  
  248.                     /* get the font name, setup name buffer ptr */
  249.                     fontMapNamePtr = fontMapPtr->fontName;
  250.                     fontNamePtr = fontStr;
  251.                     
  252.                     /* prepend the asterisk to the name */
  253.                     fontCharCount = *fontMapNamePtr++;
  254.                     *fontNamePtr++ = fontCharCount + 1;
  255.                     *fontNamePtr++ = kGhostFontChar;
  256.                     
  257.                     /* copy into name buffer */
  258.                     while (fontCharCount--)
  259.                         *fontNamePtr++ = *fontMapNamePtr++;
  260.  
  261.                     InsMenuItem (fontMenuHdl, fontStr, 999);
  262.                 }
  263.             }
  264.         }
  265.     }
  266.  
  267.     return (fontMenuHdl);
  268.  
  269. } /* buildFontMenu */
  270.  
  271.  
  272.  
  273. /* ----------------------------------------------------------
  274.     fixFontMenu -    check the correct font menu item
  275.     © 1989 by Macreations
  276. -----------------------------------------------------------*/
  277. static void
  278. fixFontMenu (theDoc, theStyle)
  279.     DocPtr            theDoc;
  280.     TextStyle            *theStyle;
  281. {
  282.     register short        i, item, menuItems;
  283.     short                font, count, base;
  284.     Str255            menuStr;
  285.     FontListHdl            ghostFontHdl;
  286.     FontListPtr            ghostFontPtr;
  287.     
  288.     menuItems = CountMItems (fontMenu);
  289.  
  290.     /* uncheck all real fonts */
  291.     for (i = 1 ; i <= menuItems; i++)
  292.     {
  293.         GetItem (fontMenu, i, menuStr);
  294.         if (menuStr[1] == '-')
  295.         {
  296.             base = i + 1;    /* the first item of the Ghost Fonts */
  297.             break;
  298.         }
  299.         font = getLocalFNum (menuStr);
  300.         CheckItem (fontMenu, i, font == theStyle->tsFont);
  301.     }
  302.     
  303.     /* now do the Ghost Fonts */
  304.     if (theDoc)
  305.     {
  306.         if (ghostFontHdl = theDoc->ghostFontList)
  307.         {
  308.             if (count = (*ghostFontHdl)->count)
  309.             {
  310.                 HLock (ghostFontHdl);
  311.                 
  312.                 ghostFontPtr = (*ghostFontHdl)->fontMap;
  313.                 
  314.                 for (i = 0; i < count; i++)
  315.                 {
  316.                     if ((base + i) > menuItems)    /* done */
  317.                         break;
  318.  
  319.                     font = ghostFontPtr->localFont;
  320.                     CheckItem (fontMenu, (i + base), font ==                             theStyle->tsFont);
  321.                     ghostFontPtr++;
  322.                 }
  323.  
  324.                 HUnlock (ghostFontHdl);
  325.             }
  326.         }
  327.     }
  328. } /* fixFontMenu */
  329.     
  330.  
  331.  
  332. /* -------------------------------------------------getLocalFNum -    return a font number corresponding to a font name
  333.     © 1989 by Macreations. All Rights Reserved
  334. ------------------------------------------------------- */
  335. short
  336. getLocalFNum (fontName)
  337.     Str255            fontName;
  338. {
  339.     register short        i, count, strLen;
  340.     short                font;
  341.  
  342.     register char        *menuNamePtr, *docNamePtr;
  343.     FontListHdl            fontListHdl; 
  344.     FontListPtr            fontListPtr;
  345.     FontMapPtr            fontMapPtr;
  346.     
  347.     /* is this a Ghost Font named with the asterisk ? */
  348.     if (fontName[1] == '*')
  349.     {
  350.         /* strip off asterisk */
  351.         fontName[0]--;
  352.         for (i = 1; i <= fontName[0]; i++)
  353.             fontName[i] = fontName[i+1];
  354.     }
  355.     
  356.     if (gTopDocument)
  357.     {
  358.         if (fontListHdl = gTopDocument->ghostFontList)
  359.         {
  360.             fontListPtr = *fontListHdl;
  361.             if (count = fontListPtr->count)
  362.             {
  363.                 fontMapPtr = fontListPtr->fontMap;
  364.             
  365.                 /* compare all names in the Ghost Font list with the 
  366.                     name passed */
  367.                 while (count--)
  368.                 {
  369.                     menuNamePtr = fontName;
  370.                     docNamePtr = fontMapPtr->fontName;
  371.                     if ((strLen = *docNamePtr++) == *menuNamePtr++)
  372.                     {
  373.                         while (strLen--)
  374.                         {
  375.                             if (*docNamePtr++ != *menuNamePtr++)
  376.                                 break;
  377.                         }
  378.  
  379.                         if (strLen < 0)    /* names compare */
  380.                             return (fontMapPtr->localFont);
  381.                     }
  382.                     fontMapPtr++;
  383.                 }
  384.             }
  385.         }
  386.     }
  387.  
  388.     /* if we got here, then its not a Ghost Font, call the system */    
  389.     GetFNum (fontName, &font);
  390.     return (font);
  391.     
  392. } /* getLocalFNum */
  393.  
  394.  
  395. /* -------------------------------------------------------    getLocalFontName    -    return the name corresponding to the font
  396.     © 1989 by Macreations. All Rights Reserved
  397. ------------------------------------------------------- */
  398. void
  399. getLocalFontName (localFont, fontName)
  400.     short                localFont;
  401.     Str255            fontName;
  402. {
  403.     short                count;
  404.     FontListHdl            fontListHdl; 
  405.     FontListPtr            fontListPtr;
  406.     FontMapPtr            fontMapPtr;
  407.     
  408.     if (gTopDocument)    
  409.     {
  410.         if (fontListHdl = gTopDocument->ghostFontList)
  411.         {
  412.             fontListPtr = *fontListHdl;
  413.             if (count = fontListPtr->count)
  414.             {
  415.                 fontMapPtr = fontListPtr->fontMap;
  416.                 while (count--)
  417.                 {
  418.                     if (fontMapPtr->localFont == localFont)
  419.                     {
  420.                         BlockMove (fontMapPtr->fontName, fontName,                            (Size)(fontMapPtr->fontName[0] + 1));
  421.                         return;
  422.                     }
  423.                     fontMapPtr++;
  424.                 }
  425.             }
  426.         }
  427.     }
  428.     
  429.     GetFontName (localFont, fontName);
  430.     if (!fontName [0])
  431.         pStrCpy (fontName, "\pUnknown Font");
  432.     
  433. } /* getLocalFontName */
  434.  
  435.